using Gobang;
using System;
using System.Collections.Generic;
using UnityEngine.Profiling;

namespace MCTS
{
    [Serializable]
    public class MonteCarloTree
    {
        public MCTSUtility.Comparer_MonteCarloTreeNode_LCB CML;
        public MonteCarloTreeNode root;

        public MonteCarloTree(ChessboardState initState)
        {
            root = new MonteCarloTreeNode(initState, null, default);
            CML = new MCTSUtility.Comparer_MonteCarloTreeNode_LCB(root);
        }

        public void Mock(int times)
        {
            int target = root.state.nextChess;
            MonteCarloTreeNode selected = root.Select();
            Profiler.BeginSample("expand");
            MonteCarloTreeNode expanded = selected.Expand();
            Profiler.EndSample();
            Profiler.BeginSample("mock");
            for (int i = 0; i < times; i++)
            {
                int winnner = expanded.Mock();
                float reward = winnner == 0 ? 0.5f : (target == winnner ? 1f : 0f);
                expanded.Backpropagation(reward);
            }
            Profiler.EndSample();
        }

        public void GetPrediction(List<PredictionPointData> ret, int count)
        {
            ret.Clear();
            List<MonteCarloTreeNode> nodes = root.children;

            nodes.Sort(CML);
            for (int i = 0; i < nodes.Count && i < count; i++)
            {
                ret.Add(new PredictionPointData(nodes[i], i + 1));
            }
        }
    }
}